import copy
import json
import os
import time
import datetime

import threading
import multiprocessing
import re
from time import strftime, localtime


# from multiprocessing import Process,Lock

class puzzle:
    def __init__(self):
        self.floorName = []
        self.floor = []
        self.module = []
        self.binama = 'utf-8'
        self.filePath = r''
        self.time = 0
        # name = ''  # 空
        # for y in range(len(self.floor)):  # 循环每一列
        #     for x in range(len(self.floor[y])):  # 循环每一行
        #         if self.floor[y][x] == -1:  # 判断是否-1，加日期
        #             name = name + self.floorName[y][x]
        self.name = ''
        self.plan = []
        self.saveFile = ''

        pass

    def nameLoc(self):
        '''
        坐标名称
        :return:
        '''
        name = ''  # 空
        for y in range(len(self.floor)):  # 循环每一列
            for x in range(len(self.floor[y])):  # 循环每一行
                if self.floor[y][x] == -1:  # 判断是否-1，加日期
                    name = name + self.floorName[y][x]
        self.name = name
        return name
        pass

    def clockwise90(self, mList=[]):  # 顺时针选择90°
        cList = []
        for c in range(len(mList)):
            # templist=[]
            if c == 0:
                for r in range(len(mList[c])):
                    cList.append([])
            for r in range(len(mList[c])):
                cList[r].insert(0, mList[c][r])
                pass
        return cList
        pass

    def vertical(self, mList=[]):  # 垂直翻转
        cList = []
        for c in range(len(mList)):
            # templist=[]
            cList.append([])
            for r in range(len(mList[c])):
                cList[c].insert(0, mList[c][r])
                pass
        return cList
        pass

    def merge(self, myfloor, module, x, y, num):  # 合并底板和模块
        '''

        :param myfloor: 底板列表
        :param module: 模块列表
        :param x: 开始x坐标
        :param y: 开始y坐标
        :param num: 模块数字
        :return:
        '''
        if x < 0 or y < 0:
            return False
        floor = copy.deepcopy(myfloor)  # 深复制底板，备份
        for my in range(len(module)):
            for mx in range(len(module[my])):
                if my + y >= len(floor) or mx + x >= len(floor[0]):  # 超过底板直接返回假
                    return False
                # print(my+y,mx+x)
                floor[my + y][mx + x] += module[my][mx]
                if module[my][mx] > 0 and floor[my + y][mx + x] != num:  # 相加数字不对直接返回假

                    return False
        myfloor = copy.deepcopy(floor)
        return myfloor
        pass

        pass

    def writeFile(self, data):
        if self.filePath == '':
            return 0
        filePath = self.filePath
        with open(filePath.format('方案详解'), "ab") as of:  # 写入data ，前后假换行
            of.write(data.encode(self.binama))
            of.write("\n".encode(self.binama))
        pass

    def writelist(self, data):
        if self.filePath == '':
            return 0
        filePath = self.filePath
        # fileContent = json.dumps(data, indent=4, ensure_ascii=False)  # json格式
        # with open(filePath, "ab") as of:  # 写入data ，前后假换行
        #     of.write(fileContent.encode(self.binama))
        # return fileContent
        for mydata in data:
            fileContent = json.dumps(mydata, ensure_ascii=False)  # json格式
            with open(filePath.format('方案详解'), "ab") as of:  # 写入data ，前后假换行
                of.write(fileContent.encode(self.binama))
                of.write("\n".encode(self.binama))
        return fileContent
        pass

    def mainFloor(self, floor, moduleJ=[], digui=''):
        # print("{}递归".format(digui))#递归顺序
        # floor=copy.deepcopy(myfloor)#备份深度复制
        if digui == '':
            moduleJ = []
        if moduleJ == []:  # 模块使用标记
            for m in range(len(self.module)):
                moduleJ.append(0)
        if moduleJ.count(0) == 0:  # 没有空模块以全部使用
            # if self.plan.count(digui) != 0:  # 递归顺序是否存在，不存在记录，记录存在，直接返回
            #     return 0
            self.plan.append(digui)
            self.time += 1
            tempStr = '第{}次-模块顺序:{}'.format(self.time, digui)
            #######################################################
            # 保存字符串
            print('{}->{}'.format(self.nameLoc(), tempStr))
            self.saveFile = self.saveFile + self.name + '\n' + tempStr + '\n'
            for mydata in floor:
                fileContent = json.dumps(mydata, ensure_ascii=False)  # json格式
                self.saveFile = self.saveFile + fileContent + '\n'
            self.saveFile = self.saveFile + '\n' * 5
            #######################################################
            # #写入文件
            # self.writeFile(self.name+'\n'+tempStr+'\n')
            # print(tempStr)
            # self.writelist(floor)
            # self.writeFile('\n'*5)
            return 0  # 返回0继续后面计算
            pass
        for y in range(len(floor)):  # 循环每一列
            for x in range(len(floor[y])):  # 循环每一行
                if floor[y][x] == 0:  # 判断坐标是否为0
                    fNum = floor[y][x]  # 确定格子的值并大约该格
                    # print('{},{},id={},digui={},id={}'.format(self.nameLoc(),moduleJ,id(moduleJ),digui,id(digui)))
                    for m in range(len(self.module)):  # 循环模块列表
                        if moduleJ[m] != 0:  # 判断是否有使用过，使用过跳过
                            continue
                        module = self.module[m]  # 模块取值
                        reuseList=[]
                        for r1 in range(4):  # 顺时针90°旋转4次
                            module = self.clockwise90(module)  # 顺时针90°旋转


                            for r2 in range(2):  # 垂直旋转2次
                                module = self.vertical(module)  # 垂直旋转
                                #判断是否重复
                                if reuseList.count(module):
                                    break
                                else:
                                    reuseList.append(module)
                                # 判断图形第一行的位置
                                module_x = 0  # x坐标位置参数
                                for module_x in range(len(module[0])):  # 循环判断第一行的非空位置
                                    if module[0][module_x] > fNum:  # 第一行的非空位置
                                        break  # 返回
                                j = 0
                                j = self.merge(floor, module, x - module_x, y, m + 1)  # 调用合并，x-module_x是修正坐标
                                if j:  # 判断合并后的返回是否为假，j为合并后返回列表
                                    moduleJ[m] = 1  # 赋值使用过的模块
                                    j1 = self.mainFloor(j, moduleJ, digui + '>' + str(m + 1))  # 递归
                                    if j1:  # 递归之后的判断
                                        return j1
                                    else:
                                        moduleJ[m] = 0  # 递归之后不能用恢复值
                    # print("{}递归退出".format(digui))#判断所有模块不可用，退出递归
                    return 0

        return 0

        pass

    def position(self, x, y):
        '''
        选择空格
        :param x:
        :param y:
        :return: 返回0是没有更改
        '''
        if y >= 0 and y < len(self.floor) and x >= 0 and x < len(self.floor[0]):  # 判断坐标在区间内

            if self.floor[y][x] == 0:
                self.floor[y][x] = -1
                return 1
            else:
                return 0
        else:
            return 0
        pass

    def namePos(self, findStr, p=0):
        '''

        :param findStr: 查找字符串
        :param p: 0返回坐标，1直接修改
        :return:
        '''
        for y in range(len(self.floorName)):
            for x in range(len(self.floorName[y])):
                if self.floorName[y][x] == findStr:
                    if p:
                        return self.position(x, y)
                    else:
                        return x, y
        return 0
        pass

    def cs(self, floor, module, x, y, m):

        pass


class floorModule():
    def __init__(self):
        self.floorName = []
        self.floor = []
        self.module = []

    def floormodule_0(self):
        '''
        网购，9模块
        :return:
        '''
        self.floorName = [
            ['01月', '02月', '03月', '04月', '05月', '06月'],
            ['07月', '08月', '09月', '10月', '11月', '12月'],
            ['01日', '02日', '03日', '04日', '05日', '06日'],
            ['07日', '08日', '09日', '10日', '11日', '12日'],
            ['13日', '14日', '15日', '16日', '17日', '18日'],
            ['19日', '20日', '21日', '22日', '23日', '24日'],
            ['25日', '26日', '27日', '28日', '29日', '30日'],
            ['31日', '    ', '    ', '周一', '周二', '周三'],
            ['    ', '    ', '周四', '周五', '周六', '周日']

        ]
        self.floor = [
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0]
        ]
        self.module_1 = [
            [1, 1, 1, 1, 1],
            [0, 0, 0, 1, 0]
        ]
        self.module_2 = [
            [0, 0, 2, 2],
            [2, 2, 2, 0]
        ]
        self.module_3 = [
            [3, 0, 0],
            [3, 3, 3],
            [0, 3, 0],
            [0, 3, 0]
        ]
        self.module_4 = [
            [4, 0, 4],
            [4, 4, 4],
            [0, 0, 4]
        ]
        self.module_5 = [
            [5, 0, 0],
            [5, 5, 5],
            [5, 0, 0],
            [5, 0, 0]
        ]
        self.module_6 = [
            [6, 0],
            [6, 6],
            [6, 6]
        ]
        self.module_7 = [
            [7, 7],
            [0, 7],
            [0, 7],
            [0, 7]
        ]
        self.module_8 = [
            [8, 8, 8],
            [0, 0, 8],
            [0, 0, 8],
            [0, 0, 8]
        ]
        self.module_9 = [
            [9, 9],
            [0, 9],
            [0, 9],
            [0, 9],
            [0, 9]
        ]
        self.module = [
            self.module_1,
            self.module_2,
            self.module_3,
            self.module_4,
            self.module_5,
            self.module_6,
            self.module_7,
            self.module_8,
            self.module_9
        ]
        return 3

    def floormodule_1(self):
        '''
        国外团队设计，GM秘密基地，8个模块
        :return:
        '''
        self.floorName = [  # 底板名字
            ['01月', '02月', '03月', '04月', '05月', '06月', '   '],
            ['07月', '08月', '09月', '10月', '11月', '12月', '   '],
            ['01日', '02日', '03日', '04日', '05日', '06日', '07日'],
            ['08日', '09日', '10日', '11日', '12日', '13日', '14日'],
            ['15日', '16日', '17日', '18日', '19日', '20日', '21日'],
            ['22日', '23日', '24日', '25日', '26日', '27日', '28日'],
            ['29日', '30日', '31日', '   ', '   ', '   ', '   ']
        ]
        self.floor = [  # 底板
            [0, 0, 0, 0, 0, 0, -2],
            [0, 0, 0, 0, 0, 0, -2],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, -2, -2, -2, -2]
        ]

        self.module_1 = [
            [0, 1],
            [1, 1],
            [0, 1],
            [0, 1]
        ]
        self.module_2 = [
            [2, 2, 0, 0],
            [0, 2, 2, 2]
        ]
        self.module_3 = [
            [3, 3, 0],
            [0, 3, 0],
            [0, 3, 3]
        ]
        self.module_4 = [
            [4, 0, 4],
            [4, 4, 4]
        ]
        self.module_5 = [
            [5, 5, 5],
            [5, 5, 5]
        ]
        self.module_6 = [
            [6, 0],
            [6, 6],
            [6, 6]
        ]
        self.module_7 = [
            [7, 7],
            [0, 7],
            [0, 7],
            [0, 7]
        ]
        self.module_8 = [
            [8, 8, 8],
            [0, 0, 8],
            [0, 0, 8]
        ]
        self.module = [
            self.module_1,
            self.module_2,
            self.module_3,
            self.module_4,
            self.module_5,
            self.module_6,
            self.module_7,
            self.module_8
        ]
        return 2

    def floormodule_2(self):
        '''
        成都团队设计，GM秘密基地，11个模块
        :return:
        '''
        self.floorName = [  # 底板名称
            ['图案', '周一', '周二', '周三', '01月', '02月', '03月', '04月'],
            ['周四', '周五', '周六', '周日', '05月', '06月', '07月', '08月'],
            ['01日', '02日', '03日', '04日', '09月', '10月', '11月', '12月'],
            ['05日', '06日', '07日', '08日', '09日', '10日', '11日', '12日'],
            ['13日', '14日', '15日', '16日', '17日', '18日', '19日', '20日'],
            ['21日', '22日', '23日', '24日', '25日', '26日', '27日', '28日'],
            ['29日', '30日', '31日', '    ', '    ', '   ', '    ', '   ']
        ]
        self.floor = [  # 底板
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, -2, -2, -2, -2, -2]
        ]

        self.module_1 = [
            [0, 1],
            [1, 1],
            [0, 1],
            [0, 1]
        ]
        self.module_2 = [
            [2, 2, 0],
            [0, 2, 2]
        ]
        self.module_3 = [
            [0, 3, 0],
            [3, 3, 3]
        ]
        self.module_4 = [
            [4, 0, 4],
            [4, 4, 4]
        ]
        self.module_5 = [
            [5, 5],
            [5, 5]
        ]
        self.module_6 = [
            [6, 0],
            [6, 6],
            [6, 6]
        ]
        self.module_7 = [
            [7, 7],
            [0, 7],
            [0, 7],
            [0, 7]
        ]
        self.module_8 = [
            [8, 8, 8],
            [0, 0, 8],
            [0, 0, 8]
        ]
        self.module_9 = [
            [9, 9, 9],
            [0, 0, 9]
        ]
        self.module_10 = [
            [10, 0],
            [10, 10]
        ]
        self.module_11 = [
            [11, 11, 11, 11]
        ]
        self.module = [
            self.module_1,
            self.module_2,
            self.module_3,
            self.module_4,
            self.module_5,
            self.module_6,
            self.module_7,
            self.module_8,
            self.module_9,
            self.module_10,
            self.module_11
        ]
        return 3

    def floormodule_3(self):
        '''
        网上看到，10模块
        :return:
        '''
        self.floorName = [  # 底板名字
            ['01月', '02月', '03月', '04月', '05月', '06月', -2],
            ['07月', '08月', '09月', '10月', '11月', '12月', -2],
            ['01日', '02日', '03日', '04日', '05日', '06日', '07日'],
            ['08日', '09日', '10日', '11日', '12日', '13日', '14日'],
            ['15日', '16日', '17日', '18日', '19日', '20日', '21日'],
            ['22日', '23日', '24日', '25日', '26日', '27日', '28日'],
            ['29日', '30日', '31日', '周日', '周一', '周二', '周三'],
            ['   ', '   ', '   ', '   ', '周四', '周五', '周六']
        ]
        self.floor = [  # 底板
            [0, 0, 0, 0, 0, 0, -2],
            [0, 0, 0, 0, 0, 0, -2],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0],
            [-2, -2, -2, -2, 0, 0, 0]
        ]

        self.module_1 = [
            [1, 1, 1, 1]
        ]
        self.module_2 = [
            [2, 2, 0],
            [0, 2, 2]
        ]
        self.module_3 = [
            [0, 3, 0],
            [0, 3, 0],
            [3, 3, 3]
        ]
        self.module_4 = [
            [4, 0, 4],
            [4, 4, 4]
        ]
        self.module_5 = [
            [5, 5, 0],
            [0, 5, 0],
            [0, 5, 5]
        ]
        self.module_6 = [
            [6, 0],
            [6, 6],
            [6, 6]
        ]
        self.module_7 = [
            [7, 7],
            [0, 7],
            [0, 7],
            [0, 7]
        ]
        self.module_8 = [
            [8, 8, 8],
            [0, 0, 8],
            [0, 0, 8]
        ]
        self.module_9 = [
            [9, 9, 9],
            [0, 0, 9]
        ]
        self.module_10 = [
            [10, 0],
            [10, 10],
            [0, 10],
            [0, 10]
        ]
        self.module = [
            self.module_1,
            self.module_2,
            self.module_3,
            self.module_4,
            self.module_5,
            self.module_6,
            self.module_7,
            self.module_8,
            self.module_9,
            self.module_10
        ]
        return 3

    def floormodule_4(self):
        '''
        自己研发
        :return:
        '''
        self.floorName = [
            ['01月', '02月', '03月', '04月', '05月', '06月'],
            ['07月', '08月', '09月', '10月', '11月', '12月'],
            ['01日', '02日', '03日', '04日', '05日', '06日'],
            ['07日', '08日', '09日', '10日', '11日', '12日'],
            ['13日', '14日', '15日', '16日', '17日', '18日'],
            ['19日', '20日', '21日', '22日', '23日', '24日'],
            ['25日', '26日', '27日', '28日', '29日', '30日'],
            ['31日', '    ', '    ', '周一', '周二', '周三'],
            ['    ', '    ', '周四', '周五', '周六', '周日']

        ]
        self.floor = [
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0]
        ]
        self.module_1 = [
            [0, 1, 0],
            [1, 1, 1],
            [0, 1, 0],
            [0, 1, 0],
            [0, 1, 0]
        ]
        self.module_2 = [
            [2, 2, 0, 0],
            [0, 2, 2, 2]
        ]
        self.module_3 = [
            [3, 0, 3],
            [3, 3, 3],
            [0, 3, 0],
            [0, 3, 0]
        ]
        self.module_4 = [
            [4, 0, 4],
            [4, 4, 4],
            [4, 0, 4]
        ]
        self.module_5 = [
            [0, 0, 5],
            [0, 0, 5],
            [5, 5, 5],
            [0, 0, 5],
            [0, 0, 5]
        ]
        self.module_6 = [
            [6, 0],
            [6, 6],
            [6, 6]
        ]
        self.module_7 = [
            [8, 8, 8],
            [0, 0, 8],
            [0, 0, 8],
            [0, 0, 8],
            [0, 0, 8]
        ]
        self.module_8 = [
            [9, 9],
            [0, 9],
            [0, 9],
            [0, 9],
            [0, 9]
        ]
        self.module = [
            self.module_1,
            self.module_2,
            self.module_3,
            self.module_4,
            self.module_5,
            self.module_6,
            self.module_7,
            self.module_8
        ]
        return 3

    def position(self, col, row):
        '''
        选择空格
        :param x:
        :param y:
        :return: 返回0是没有更改
        '''
        if row >= 0 and row < len(self.floor) and col >= 0 and col < len(self.floor[0]):  # 判断坐标在区间内

            if self.floor[row][col] == 0:
                self.floor[row][col] = -1
                return 1
            else:
                return 0
        else:
            return 0
        pass

    def nameLoc(self):
        '''
        生成模板名称，坐标名称合并
        :return:
        '''
        name = ''  # 空
        for y in range(len(self.floor)):  # 循环每一列
            for x in range(len(self.floor[y])):  # 循环每一行
                if self.floor[y][x] == -1:  # 判断是否-1，加日期
                    name = name + self.floorName[y][x]
        self.name = name
        return name

    def namePos(self, findStr, p=0):
        '''

        :param findStr: 查找字符串,查位置（二维转一维的数字）
        :param p: 0返回坐标，1直接修改
        :return:
        '''
        for y in range(len(self.floorName)):
            for x in range(len(self.floorName[y])):

                if self.floorName[y][x] == findStr or findStr == 0:
                    if p:
                        return self.position(x, y)
                    else:
                        return x, y

                if type(findStr) == int:
                    findStr = findStr - 1
        return 0
        pass

    def spaceNum(self):
        fNum = 0
        for a in self.floor:
            for b in a:
                if b == 0:
                    fNum += 1
        return fNum

    def checkFlooor(self):  # 检查底板模块是否正确
        sNum = self.floormodule_3()
        print(sNum)
        fNum = 0
        for a in self.floor:
            for b in a:
                if b == 0:
                    fNum += 1
        print(fNum)
        for a in self.module:
            for b in a:
                for c in b:
                    if c != 0:
                        fNum -= 1
        print(fNum)
        if sNum == fNum:
            print('正确')
        pass


class op():
    def __init__(self):
        self.p = puzzle()
        self.f = floorModule()
        self.filePath = r""
        self.threadTable = 0

    def computePuzzle(self, path='', puzzle_n=-1, puzzle_date=[]):
        '''单个计算'''
        # self.filePath = path
        # f = floorModule()
        print("computePuzzle->",path)
        fModule = [self.f.floormodule_0, self.f.floormodule_1, self.f.floormodule_2, self.f.floormodule_3]
        i = 0
        if puzzle_n == -1:
            for fm in fModule:  # 遍历打印拼图
                fm()
                i += 1
                print('{}号拼图版'.format(i))
                for n in self.f.floorName:  # 打印每行名称
                    print(n)
                print('-' * 99)
        while 1:
            if puzzle_n != -1:
                n = puzzle_n
            else:
                n = input('请输入选择的拼图板号：')  # 输入谱图号
            n = int(n)
            if n > 0 and n < len(fModule) + 1:
                break
        path = path.format("第{}板-{}".format(n, "{}"))
        fm = fModule[int(n) - 1]  # 读取拼图

        space = fm()
        for n in self.f.floorName:  # 打印每行名称
            print(n)
        i = 0
        tempList = ['月份', '日', '星期']

        while 1:  # 月份日期周选择
            if puzzle_date:
                findStr = puzzle_date[i]
            else:
                findStr = input('请输入选择{}：'.format(tempList[i]))

            mybool = self.f.namePos(findStr, 1)

            if mybool:
                i += 1
            else:
                print("请重新输入")
            if i >= space: break
        datename = self.f.nameLoc()
        path = path.format(datename + '-方案详解')
        print("开始计算拼图",path)
        if os.path.exists(path):
            temp=self.readFile(path)
            print(temp,"\n")
            # path=path.replace("-方案详解","-方案详解-简版")
            # if not os.path.exists(path):
            #     self.writeFile(temp,path)# 写入方案简版 ，
            # pass
            return 1
        else:
            p = self.compute(self.f)
            if path:
                self.writeFile(p.saveFile, path)  # 写入方案详解 ，
                temp = self.readFile(path)
                path=path.replace("-方案详解","-方案详解-简版")
                if not os.path.exists(path):
                    self.writeFile(temp, path)  # 写入方案简版 ，
            return p
        pass

    def compute(self, myclass):
        '''全深度复制'''
        start = datetime.datetime.now()

        p = puzzle()
        p.floor = copy.deepcopy(myclass.floor)  # 赋值底板，给计算类
        p.floorName = copy.deepcopy(myclass.floorName)  # 赋值底板名称，给计算类
        p.filePath = copy.deepcopy(self.filePath.format(p.nameLoc()))  # 重置地址
        p.module = copy.deepcopy(myclass.module)  # 赋值底板模块，给计算类
        time.sleep(1)
        self.threadTable = 0
        print("开始计算")
        p.mainFloor(p.floor)  # 计算
        # p.mainFloor(p.floor,moduleJ=[],digui='')  # 计算
        end = datetime.datetime.now()
        print('结束时间：{}，运行用时：{}'.format(end, end - start))
        return p
        pass

    def all_compute(self, filePath=''):
        '''遍历所有格子，如：第一张板是54个格子，计算量是54*53*52'''

        def module_com(puzzle_n, f, digui, filePath='', start=-1, spaceList=[]):
            '''

            :param p: 第p个puzzle
            :param f: 类
            :param digui: 递归次数
            :param filePath: 文件地址
            :param start: 开始
            :param spaceList: 列表参数
            :return:
            '''
            if digui > 0:  # 判断递归次数
                for a in range(start + 1, f.spaceNum()):  # 循环开始到结尾
                    spaceList.append(a)  # 记录数据
                    module_com(puzzle_n, f, digui - 1, filePath, a, spaceList)
                    spaceList.pop()  # 推出数据
                    pass
            else:
                print(spaceList)
                filePath=filePath.format("all.{}")
                p = self.computePuzzle(filePath, puzzle_n=puzzle_n + 1, puzzle_date=spaceList)
                # data = '\n' + p.nameLoc() + '方案共：' + str(p.time) + '\n'  # 合并数据
                # if filePath:
                #     self.writeFile(data+p.saveFile, filePath, "所有格子.第{}板-{}".format(p, "-方案详解"))  # 写入方案详解 ，
                # return pu
                pass
                ######################################################
                # p.floor = copy.deepcopy(f.floor)  # 深度复制
                # p.floorName=f.floorName
                # p.module=f.module
                # data=''
                # for a in spaceList:#去除数据
                #     if p.floor[a // 6][a % 6] == 0:
                #         data=data+str(a // 6) + ',' + str(a % 6) + '->'
                #         p.floor[a // 6][a % 6]=-1
                #         pass
                #     else:
                #         return 0
                #     pass
                # data=data+ '\n' + p.nameLoc()
                # print(data)
                # p.time = 0  # 记录次数重置
                # p.plan=[]# 记录重置
                # p.mainFloor(p.floor)  # 调用主计算函数
                # data=data+ '\n' + '方案共：' + str(p.time)+ '\n'#合并数据
                # # print(data)
                # # for plan in p.plan:#方案顺序
                # #     data=data+plan+ '\n'
                # data+='-'*99#分隔符
                # data+= '\n'*2#加空格分开
                # if filePath=='':
                #     print(data)
                #     return 0
                # with open(filePath.format("方案"), "ab") as of:  # 写入data ，前后假换行
                #     of.write(data.encode(p.binama))
                #     of.write("\n\n\n".encode(p.binama))
                # if p.time == 0:  # 没有解法的
                #     with open(filePath.format("无方案"), "ab") as of:  # 写入data ，前后假换行
                #         of.write(data.encode(p.binama))
                #         of.write("\n\n\n".encode(p.binama))
                #     pass

        f = self.f = floorModule()
        fModuleList = [f.floormodule_0, f.floormodule_1, f.floormodule_2, f.floormodule_3]

        for i in range(len(fModuleList)):
            # for fModule in fModuleList:
            n = fModuleList[i]()
            p = module_com(i, f, n, filePath)
            # if filePath:
            #     self.writeFile(p.saveFile, filePath, "所有格子.第{}板-{}".format(p, "-方案详解"))  # 写入方案详解 ，

        pass

    def all_date_compute(self, puzzle_n, class_o, date_l, digui, spaceList=[]):

        loc = len(date_l) - digui
        # threadLock = threading.Lock()
        # ------------多线程方案---------------
        if digui == 1:  # 多线程方案
            mythread = []
            mycalssL = []
        # ------------多线程方案---------------
        if loc < len(date_l):

            for date in date_l[loc]:
                spaceList.append(date)
                self.all_date_compute(puzzle_n, self.f, date_l, digui - 1, spaceList)  # 计算方案
                spaceList.pop()
                continue
                #################20220403以前######################
                pos = self.f.namePos(date, 0)  # 取值
                x, y = -1, -1
                if type(pos) == tuple:  # 判断是否为元组
                    x, y = pos[0], pos[1]
                else:  # 返回为假或者真都跳过该条
                    continue
                if self.f.position(x, y):  # 修改底板返回真
                    # self.all_date_compute(date_l,digui-1)#计算方案
                    # #------------多线程方案---------------
                    # if digui == 1:  # 多线程方案
                    #     # self.p = puzzle()
                    #     # self.p.floor = copy.deepcopy(self.f.floor)  # 底板深度复制
                    #     # self.p.floorName = copy.deepcopy(self.f.floorName)  # 底板名称
                    #     # self.p.module = copy.deepcopy(self.f.module)  # 模块
                    #     # self.p.floorName = self.f.floorName  # 底板名称
                    #     # self.p.module = self.f.module  # 模块
                    #     # self.p.time=0
                    #     # self.p.plan=[]
                    #     # print('{}{}'.format(self.p.nameLoc(),self.p))
                    #     self.threadTable=1#设置标记
                    #     threadTemp = myClass.myThread.returnThread(function=self.all_date_compute,args=(self.f, date_l, digui - 1))
                    #     threadTemp.start()
                    #     mycalssL.append(self.p)
                    #     mythread.append(threadTemp)
                    #     temp_i=0
                    #     while self.threadTable:
                    #         temp_i+=1
                    #         # print(temp_i)
                    #         # time.sleep(temp_i)
                    #         pass
                    # else:
                    #     self.all_date_compute(self.p,date_l, digui - 1)  # 计算方案
                    # # ------------多线程方案---------------
                    # ---------------单进程单线程
                    self.all_date_compute(self.f, date_l, digui - 1)  # 计算方案
                    self.f.floor[y][x] = 0  # 恢复为0
                    self.computePuzzle()
                    pass
                else:
                    return 0
            # # ------------多线程方案---------------
            # if digui == 1:  # 多线程方案
            #     while 1:  # 死循环查看线程列表
            #         thread_stop = []
            #         for ithread in mythread:  # 开始的线程一个个取出
            #             if ithread.is_alive() == False:  # 判断是否存在，不存在，压入线程停止列表
            #                 # print(ithread, ithread.getName(), ithread.name, ithread.daemon, ithread.ident,ithread.function_return)
            #                 thread_stop.append(ithread)  # 压入线程停止列表
            #         for ithread in thread_stop:  # 充线程停止列表中取数据，
            #             mythread.pop(mythread.index(ithread))  # 定位停止的线程，在开始列表中删除
            #         if mythread == []:  # 线程列表空退出
            #             break
            # # ------------多线程方案---------------
            pass
        else:
            print(spaceList)
            p = 0
            filePath = self.filePath
            p = self.computePuzzle(filePath,puzzle_n=puzzle_n, puzzle_date=spaceList)
            # data = '\n' + p.nameLoc() + '方案共：' + str(p.time) + '\n'  # 合并数据
            # filePath = self.filePath
            # if filePath:
            #     self.writeFile(data + p.saveFile, filePath, "-方案详解")  # 写入方案详解 ，
            return p
            #################20220403以前######################
            data = ''
            data = data + '\n' + class_o.nameLoc()
            print(data)
            r_class = self.compute(class_o)
            data = data + '\n' + '方案共：' + str(r_class.time) + '\n'  # 合并数据
            # print(data)
            data += '-' * 99  # 分隔符
            data += '\n' * 2  # 加空格分开
            filePath = self.filePath
            if filePath == '':
                print(data)
                return 0
            # ------------多线程方案---------------
            # ------------互斥写文件---------------
            threadLock.acquire()
            self.writeFile(r_class.saveFile, filePath, '方案详解')  # 写入方案详解 ，
            self.writeFile(data, filePath, '方案')  # 写入data ，
            self.writeFile(data, filePath, '无方案')  # 写入data ，
            threadLock.release()
            return 1
            pass
        pass

    def all_date_compute_thread(self, class_o, date_l, digui):

        loc = len(date_l) - digui
        # threadLock = threading.Lock()
        # ------------多线程方案---------------
        if digui == 1:  # 多线程方案
            mythread = []
            mycalssL = []
        # ------------多线程方案---------------
        if loc < len(date_l):

            for date in date_l[loc]:
                pos = self.f.namePos(date, 0)  # 取值
                x, y = -1, -1
                if type(pos) == tuple:  # 判断是否为元组
                    x, y = pos[0], pos[1]
                else:  # 返回为假或者真都跳过该条
                    continue
                if self.f.position(x, y):  # 修改底板返回真
                    # self.all_date_compute(date_l,digui-1)#计算方案
                    # ------------多线程方案---------------
                    if digui == 1:  # 多线程方案
                        # self.p = puzzle()
                        # self.p.floor = copy.deepcopy(self.f.floor)  # 底板深度复制
                        # self.p.floorName = copy.deepcopy(self.f.floorName)  # 底板名称
                        # self.p.module = copy.deepcopy(self.f.module)  # 模块
                        # self.p.floorName = self.f.floorName  # 底板名称
                        # self.p.module = self.f.module  # 模块
                        # self.p.time=0
                        # self.p.plan=[]
                        # print('{}{}'.format(self.p.nameLoc(),self.p))
                        self.threadTable = 1  # 设置标记
                        threadTemp = myClass.myThread.returnThread(function=self.all_date_compute,
                                                                   args=(self.f, date_l, digui - 1))
                        threadTemp.start()
                        mycalssL.append(self.p)
                        mythread.append(threadTemp)
                        temp_i = 0
                        while self.threadTable:
                            temp_i += 1
                            # print(temp_i)
                            # time.sleep(temp_i)
                            pass
                    else:
                        self.all_date_compute(self.p, date_l, digui - 1)  # 计算方案
                    # ------------多线程方案---------------
                    # ---------------单进程单线程
                    # self.all_date_compute(self.f, date_l, digui - 1)  # 计算方案
                    self.f.floor[y][x] = 0  # 恢复为0
                    pass
                else:
                    return 0
            # ------------多线程方案---------------
            if digui == 1:  # 多线程方案
                while 1:  # 死循环查看线程列表
                    thread_stop = []
                    for ithread in mythread:  # 开始的线程一个个取出
                        if ithread.is_alive() == False:  # 判断是否存在，不存在，压入线程停止列表
                            # print(ithread, ithread.getName(), ithread.name, ithread.daemon, ithread.ident,ithread.function_return)
                            thread_stop.append(ithread)  # 压入线程停止列表
                    for ithread in thread_stop:  # 充线程停止列表中取数据，
                        mythread.pop(mythread.index(ithread))  # 定位停止的线程，在开始列表中删除
                    if mythread == []:  # 线程列表空退出
                        break
            # ------------多线程方案---------------
            pass
        else:
            data = ''
            data = data + '\n' + class_o.nameLoc()
            print(data)
            r_class = self.compute(class_o)
            data = data + '\n' + '方案共：' + str(r_class.time) + '\n'  # 合并数据
            # print(data)
            data += '-' * 99  # 分隔符
            data += '\n' * 2  # 加空格分开
            filePath = self.filePath
            if filePath == '':
                print(data)
                return 0
            # threadLock.acquire()
            # print(data)
            # threadLock.release()
            # ------------多线程方案---------------
            # ------------互斥写文件---------------
            threadLock.acquire()
            self.writeFile(r_class.saveFile, filePath, '方案详解')  # 写入方案详解 ，
            self.writeFile(data, filePath, '方案')  # 写入data ，
            self.writeFile(data, filePath, '无方案')  # 写入data ，
            threadLock.release()
            return 1
            pass
        pass

    def all_date_compute_pro(self, class_o, date_l, digui):

        loc = len(date_l) - digui
        # ------------多进程方案---------------
        if digui == 1:  # 多进程方案
            myMultipro = []
            mycalssL = []
        # ------------多进程方案---------------
        if loc < len(date_l):

            for date in date_l[loc]:
                pos = self.f.namePos(date, 0)  # 取值
                x, y = -1, -1
                if type(pos) == tuple:  # 判断是否为元组
                    x, y = pos[0], pos[1]
                else:  # 返回为假或者真都跳过该条
                    continue
                if self.f.position(x, y):  # 修改底板返回真
                    # ---------------单进程单线程
                    # ------------多进程方案---------------
                    # if digui == 1:  # 多进程方案
                    #     self.threadTable=1
                    #     p=multiprocessing.process(target=self.all_date_compute,args=(self.f, date_l, digui - 1))
                    #     # p = myClass.myThread.returnMultiprocessing(function=self.all_date_compute, args=(self.f, date_l, digui - 1))
                    #     p.start()
                    #     myMultipro.append(p)
                    #     temp=0
                    #     while self.threadTable:
                    #         temp+=1
                    # else:
                    #     self.all_date_compute(self.f, date_l, digui - 1)  # 计算方案
                    # ------------多进程方案---------------
                    self.all_date_compute(self.f, date_l, digui - 1)  # 计算方案
                    self.f.floor[y][x] = 0  # 恢复为0
                    pass
                else:
                    return 0
            # ------------多进程方案---------------
            if digui == 1:  # 多进程方案
                while 1:  # 死循环查看线程列表
                    myMultipro_stop = []
                    for ithread in myMultipro:  # 开始的线程一个个取出
                        if ithread.is_alive() == False:  # 判断是否存在，不存在，压入线程停止列表
                            print(ithread, ithread.name, ithread.daemon, ithread.ident, ithread.function_return)
                            myMultipro_stop.append(ithread)  # 压入线程停止列表
                    for ithread in myMultipro_stop:  # 充线程停止列表中取数据，
                        myMultipro.pop(myMultipro.index(ithread))  # 定位停止的线程，在开始列表中删除
                    if myMultipro == []:  # 线程列表空退出
                        break

            pass
        else:
            print("979开始")
            # data=''
            # data = data + '\n' + class_o.nameLoc()
            # print(data )
            # r_class=self.compute(class_o)
            # data = data + '\n' + '方案共：' + str(r_class.time) + '\n'  # 合并数据
            # print(data)
            # data += '-' * 99  # 分隔符
            # data += '\n' * 2  # 加空格分开
            # filePath=self.filePath
            # if filePath == '':
            #     print(data)
            #     return 0
            # print(data)
            # ------------多进程方案---------------
            # ------------互斥写文件---------------
            # threadLock.acquire()
            # self.writeFile(r_class.saveFile, filePath, '方案详解')  # 写入方案详解 ，
            # self.writeFile(data, filePath, '方案')  # 写入data ，
            # self.writeFile(data,filePath,'无方案')# 写入data ，
            # threadLock.release()
            return 1
            pass
        pass

    def all_date(self, filePath=""):
        '''
        遍历每一天的每一个星期
        :return:
        '''
        month_l = ['01月', '02月', '03月', '04月', '05月', '06月', '07月', '08月', '09月', '10月', '11月', '12月']
        day_l = [
            '01日', '02日', '03日', '04日', '05日', '06日',
            '07日', '08日', '09日', '10日', '11日', '12日',
            '13日', '14日', '15日', '16日', '17日', '18日',
            '19日', '20日', '21日', '22日', '23日', '24日',
            '25日', '26日', '27日', '28日', '29日', '30日',
            '31日'
        ]
        week_l = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
        date_l = [month_l, day_l, week_l]

        # self.p = puzzle()
        self.f = floorModule()
        fModuleList = [self.f.floormodule_0, self.f.floormodule_1, self.f.floormodule_2, self.f.floormodule_3,
                       self.f.floormodule_4]

        # # 测试
        # month_l = ['01月']
        # day_l = ['01日']
        # week_l = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
        # date_l = [month_l, day_l, week_l]
        # fModuleList = [self.f.floormodule_0]

        num = 0
        for fModule in fModuleList:
            if filePath != '':  # 判断有没有地址
                num += 1
                # self.filePath = filePath.format("第{}板-{}".format(num, "{}"))  # 重置地址
                self.filePath = filePath
            n = fModule()
            temp_l = []
            for i in range(n):
                temp_l.append(date_l[i])
            # self.p.floor=copy.deepcopy(self.f.floor) #底板深度复制
            # self.p.floorName=self.f.floorName#底板名称
            # self.p.module=self.f.module#模块
            # self.p.filePath=self.filePath#文件写入地址
            self.all_date_compute(num, self.p, temp_l, n)

        pass

    def mytime(self, timedelta_days=0):
        # from time import strftime, localtime
        # outtime=localtime()
        # print(outtime)
        dt = datetime.datetime.now() + datetime.timedelta(days=timedelta_days)
        localtime = dt.timetuple()  # datetime格式转换为时间元组
        # localtime = time.localtime(time.time())
        year = strftime("%Y", localtime)
        mon = strftime("%m", localtime)
        day = strftime("%d", localtime)
        hour = strftime("%H", localtime)
        min = strftime("%M", localtime)
        sec = strftime("%S", localtime)
        week_n = strftime("%w", localtime)
        week = {
            # 0:"周一",
            # 1:"周二",
            # 2:"周三",
            # 3:"周四",
            # 4:"周五",
            # 5:"周六",
            # 6:"周日"

            0: "周日",
            1: "周一",
            2: "周二",
            3: "周三",
            4: "周四",
            5: "周五",
            6: "周六"

        }
        print(year + "年" + mon + "月" + day + "日", hour + ":" + min + ":" + sec, week[int(week_n)])
        return mon + "月", day + "日", week[int(week_n)]

    def writeFile(self, data, filePath, pathStr=''):
        #文件夹判断
        if os.path.exists(filePath) == False:
            tempDir = filePath[:filePath.rfind("\\")]
            if os.path.exists(tempDir) == False:
                os.makedirs(tempDir, mode=511, exist_ok=False)  # 创建文件夹
                # print("{} - 文件夹创建完成".format(tempDir))
            else:
                # print("{} - 文件夹已经创建".format(tempDir))
                pass
        #打开文件
        with open(filePath, "ab") as of:  # 写入data ，前后假换行
            of.write(data.encode(self.p.binama))
            of.write("\n\n\n".encode(self.p.binama))
        pass

    def readFile(self, filePath):
        with open(filePath, "rb") as of:  # 写入data ，前后假换行
            rstr = of.read().decode(self.p.binama)
        pattern = re.compile(r'.*月.*\n.*', re.I)
        pstrList = pattern.findall(rstr)
        tempstr=""
        for temp in pstrList:
            temp = re.sub(r'\s', '->', temp)
            # print(temp)
            tempstr=tempstr+temp+"\n"
        return tempstr
        pass


if __name__ == '__main__':
    threadLock = threading.Lock()  # 递归锁
    start = datetime.datetime.now()
    print(start)

    filePath = r'resources\puzzle.{}.txt'  # 存放地址
    op = op()
    while 1:
        select=int(input("1.时间差选择，距离今天多少天\n2.自助输入日期\n请输入："))
        if select==1:
            days = int(input('今天的时间差{}：'.format("(正数后n天)")))
            mydate = op.mytime(days)
            break
        elif select==2:
            mydate = []
            break
        else:
            print("重新输入")
    op.computePuzzle(filePath, puzzle_date=mydate)
    # op.all_compute(filePath)

    # op.all_date(filePath)
    end = datetime.datetime.now()

    print('结束时间：{}，运行用时：{}'.format(end, end - start))
    time.sleep(5)
    input("\n按下回车键继续...")
